package com.joker.demo.admin.controller;

import com.joker.demo.admin.common.Result;
import com.joker.demo.admin.domain.dto.ExecutorStatisticsQueryDTO;
import com.joker.demo.admin.domain.dto.ThreadPoolMonitorQueryDTO;
import com.joker.demo.admin.domain.po.EnvironmentMonitorPO;
import com.joker.demo.admin.domain.po.ThreadPoolMonitorPO;
import com.joker.demo.admin.domain.vo.DashboardOverviewVO;
import com.joker.demo.admin.domain.vo.EnvironmentMonitorVO;
import com.joker.demo.admin.domain.vo.EnvironmentOverviewVO;
import com.joker.demo.admin.domain.vo.ExecutorDetailVO;
import com.joker.demo.admin.domain.vo.ExecutorListItemVO;
import com.joker.demo.admin.domain.vo.ExecutorRuntimeOverviewVO;
import com.joker.demo.admin.domain.vo.ExecutorRuntimeVO;
import com.joker.demo.admin.domain.vo.ExecutorStatisticsVO;
import com.joker.demo.admin.domain.vo.ExecutorTrendVO;
import com.joker.demo.admin.domain.vo.OnlineExecutorTrendVO;
import com.joker.demo.admin.domain.vo.OverallStatisticsVO;
import com.joker.demo.admin.domain.vo.PageResult;
import com.joker.demo.admin.domain.vo.ThreadPoolOverviewVO;
import com.joker.demo.admin.service.EnvironmentMonitorService;
import com.joker.demo.admin.service.ExecutorRuntimeService;
import com.joker.demo.admin.service.ThreadPoolMonitorService;
import com.joker.demo.admin.util.DateTimeConverterUtil;
import com.joker.demo.admin.util.EnvironmentMonitorConvertUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 仪表盘Controller - 整合所有监控数据
 *
 * @author : feixiang.li
 * @since : 2025-01-27 10:00
 */
@Slf4j
@RestController
@RequestMapping("/api/dashboard")
@Tag(name = "仪表盘", description = "仪表盘相关接口，整合所有监控数据")
@CrossOrigin
public class DashboardController {

    @Resource
    private ExecutorRuntimeService executorRuntimeService;

    @Resource
    private ThreadPoolMonitorService threadPoolMonitorService;

    @Resource
    private EnvironmentMonitorService environmentMonitorService;

    /**
     * 获取首页概览数据
     */
    @GetMapping("/overview")
    @Operation(summary = "获取首页概览数据", description = "获取首页展示的所有执行器统计信息和运行情况")
    public Result<DashboardOverviewVO> getDashboardOverview() {
        try {
            DashboardOverviewVO overview = new DashboardOverviewVO();

            // 1. 获取执行器运行情况概览
            ExecutorRuntimeOverviewVO runtimeOverview = executorRuntimeService.getRuntimeOverview();
            overview.setExecutorRuntime(runtimeOverview);

            // 2. 获取线程池监控概览（使用24小时汇总数据）
            List<ThreadPoolMonitorPO> threadPoolSummaryData = threadPoolMonitorService.query24HourSummaryData();
            ThreadPoolOverviewVO threadPoolOverview = calculateThreadPoolOverview(threadPoolSummaryData);
            overview.setThreadPoolOverview(threadPoolOverview);

            // 3. 获取环境监控概览（使用24小时汇总数据）
            List<EnvironmentMonitorPO> envSummaryData = environmentMonitorService.query24HourSummaryData();
            EnvironmentOverviewVO environmentOverview = calculateEnvironmentOverview(envSummaryData);
            overview.setEnvironmentOverview(environmentOverview);

            // 4. 计算总体统计
            OverallStatisticsVO overallStats = calculateOverallStatistics(runtimeOverview, threadPoolOverview, environmentOverview);
            overview.setOverallStats(overallStats);

            return Result.success(overview);

        } catch (Exception e) {
            log.error("获取仪表盘概览数据失败", e);
            return Result.error("获取概览数据失败：" + e.getMessage());
        }
    }

    /**
     * 获取执行器详情数据
     */
    @GetMapping("/executor/{registerKey}")
    @Operation(summary = "获取执行器详情数据", description = "获取指定执行器的详细监控数据，包括线程池、环境、JVM等信息")
    public Result<ExecutorDetailVO> getExecutorDetail(
            @Parameter(description = "执行器标识") @PathVariable("registerKey") String registerKey) {
        try {
            ExecutorDetailVO detail = new ExecutorDetailVO();

            // 1. 获取执行器运行情况
            ExecutorRuntimeVO runtimeDetail = executorRuntimeService.getExecutorRuntime(registerKey);
            if (runtimeDetail != null) {
                detail.setRegisterKey(runtimeDetail.getRegisterKey());
                detail.setAppName(runtimeDetail.getAppName());
                detail.setStatus(runtimeDetail.getStatus());
                detail.setHealthStatus(runtimeDetail.getHealthStatus());
                detail.setLastHeartbeatTime(runtimeDetail.getLastHeartbeatTime());
            }

            // 2. 获取线程池监控数据（使用24小时汇总数据）
            ThreadPoolMonitorPO threadPoolSummaryData = threadPoolMonitorService.query24HourSummaryDataByRegisterKey(registerKey);
            if (threadPoolSummaryData != null) {
                detail.setMonitorTime(threadPoolSummaryData.getMonitorTime());
                detail.setCorePoolSize(threadPoolSummaryData.getCorePoolSize());
                detail.setMaximumPoolSize(threadPoolSummaryData.getMaximumPoolSize());
                detail.setPoolSize(threadPoolSummaryData.getPoolSize());
                detail.setActiveCount(threadPoolSummaryData.getActiveCount());
                detail.setQueueSize(threadPoolSummaryData.getQueueSize());
                detail.setQueueRemainingCapacity(threadPoolSummaryData.getQueueRemainingCapacity());
                detail.setCompletedTaskCount(threadPoolSummaryData.getCompletedTaskCount());
                detail.setTaskCount(threadPoolSummaryData.getTaskCount());
                detail.setRunningTaskCount(threadPoolSummaryData.getRunningTaskCount());
                detail.setDelayTaskCount(threadPoolSummaryData.getDelayTaskCount());
                detail.setCompletedTasksLastMinute(threadPoolSummaryData.getCompletedTasksLastMinute());
                detail.setFailedTasksLastMinute(threadPoolSummaryData.getFailedTasksLastMinute());
                detail.setAverageTaskExecutionTimeMs(threadPoolSummaryData.getAverageTaskExecutionTimeMs());
                detail.setMemoryUsagePercent(threadPoolSummaryData.getMemoryUsagePercent());
                detail.setUsedMemoryMb(threadPoolSummaryData.getUsedMemoryMb());
                detail.setMaxMemoryMb(threadPoolSummaryData.getMaxMemoryMb());
            }

            // 3. 获取环境监控数据（使用24小时汇总数据）
            EnvironmentMonitorPO envSummaryData = environmentMonitorService.query24HourSummaryDataByRegisterKey(registerKey);
            detail.setEnvironmentData(envSummaryData != null ? EnvironmentMonitorConvertUtils.convertToVO(envSummaryData) : null);

            // 4. 获取环境监控历史数据（最近24小时）
            LocalDateTime endTime = LocalDateTime.now();
            LocalDateTime startTime = endTime.minusHours(24);
            List<EnvironmentMonitorPO> envHistory = environmentMonitorService.queryMonitorDataHistory(
                    registerKey, DateTimeConverterUtil.toDate(startTime), DateTimeConverterUtil.toDate(endTime), 1000);
            List<EnvironmentMonitorVO> envHistoryVO = envHistory.stream()
                    .map(EnvironmentMonitorConvertUtils::convertToVO)
                    .collect(Collectors.toList());
            detail.setEnvironmentHistory(envHistoryVO);

            // 5. 获取线程池统计信息
            ExecutorStatisticsQueryDTO queryDTO = new ExecutorStatisticsQueryDTO();
            queryDTO.setQueryDate(LocalDate.now().toString());
            queryDTO.setRegisterKey(registerKey);
            ExecutorStatisticsVO threadPoolStats = threadPoolMonitorService.queryExecutorStatistics(queryDTO);
            detail.setThreadPoolStatistics(threadPoolStats);

            return Result.success(detail);

        } catch (Exception e) {
            log.error("获取执行器详情数据失败，registerKey：{}", registerKey, e);
            return Result.error("获取执行器详情失败：" + e.getMessage());
        }
    }

    /**
     * 获取执行器24小时运行趋势
     */
    @GetMapping("/executor/{registerKey}/trend")
    @Operation(summary = "获取执行器24小时运行趋势", description = "获取指定执行器最近24小时的运行趋势数据")
    public Result<ExecutorTrendVO> getExecutorTrend(
            @Parameter(description = "执行器标识") @PathVariable("registerKey") String registerKey,
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        try {
            ExecutorTrendVO trend = new ExecutorTrendVO();

            // 如果没有指定时间范围，默认查询最近24小时
            if (startTime == null) {
                startTime = LocalDateTime.now().minusHours(24);
            }
            if (endTime == null) {
                endTime = LocalDateTime.now();
            }

            // 1. 获取线程池监控趋势 - 使用分页查询替代
            ThreadPoolMonitorQueryDTO threadPoolQuery = new ThreadPoolMonitorQueryDTO();
            threadPoolQuery.setRegisterKey(registerKey);
            threadPoolQuery.setStartTime(startTime);
            threadPoolQuery.setEndTime(endTime);
            threadPoolQuery.setPageNum(1);
            threadPoolQuery.setPageSize(24);
            PageResult<ThreadPoolMonitorPO> threadPoolPageResult = threadPoolMonitorService.queryMonitorData(threadPoolQuery);
            trend.setThreadPoolTrend(threadPoolPageResult.getRecords());

            // 2. 获取环境监控趋势
            List<EnvironmentMonitorPO> envTrend = environmentMonitorService.queryMonitorDataHistory(
                    registerKey, java.sql.Date.valueOf(startTime.toLocalDate()), java.sql.Date.valueOf(endTime.toLocalDate()), 24);
            List<EnvironmentMonitorVO> envTrendVO = envTrend.stream()
                    .map(EnvironmentMonitorConvertUtils::convertToVO)
                    .collect(Collectors.toList());
            trend.setEnvironmentTrend(envTrendVO);

            return Result.success(trend);

        } catch (Exception e) {
            log.error("获取执行器运行趋势失败，registerKey：{}", registerKey, e);
            return Result.error("获取运行趋势失败：" + e.getMessage());
        }
    }

    /**
     * 获取所有执行器列表（用于下拉选择）
     */
    @GetMapping("/executors")
    @Operation(summary = "获取所有执行器列表", description = "获取所有注册的执行器列表，用于前端下拉选择")
    public Result<List<ExecutorListItemVO>> getAllExecutors() {
        try {
            List<ExecutorRuntimeVO> allExecutors = executorRuntimeService.getAllExecutorRuntime();
            
            List<ExecutorListItemVO> executorList = allExecutors.stream()
                    .map(executor -> {
                        ExecutorListItemVO executorInfo = new ExecutorListItemVO();
                        executorInfo.setRegisterKey(executor.getRegisterKey());
                        executorInfo.setAppName(executor.getAppName());
                        executorInfo.setStatus(executor.getStatus());
                        executorInfo.setHealthStatus(executor.getHealthStatus());
                        return executorInfo;
                    })
                    .collect(Collectors.toList());

            return Result.success(executorList);

        } catch (Exception e) {
            log.error("获取执行器列表失败", e);
            return Result.error("获取执行器列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取在线执行器趋势
     */
    @GetMapping("/online-executors/trend")
    @Operation(summary = "获取在线执行器趋势", description = "获取最近24小时在线执行器数量的趋势")
    public Result<OnlineExecutorTrendVO> getOnlineExecutorsTrend() {
        try {
            OnlineExecutorTrendVO trend = executorRuntimeService.queryOnlineExecutorTrend();
            return Result.success(trend);

        } catch (Exception e) {
            log.error("获取在线执行器趋势失败", e);
            return Result.error("获取在线执行器趋势失败：" + e.getMessage());
        }
    }

    /**
     * 计算线程池概览数据
     */
    private ThreadPoolOverviewVO calculateThreadPoolOverview(List<ThreadPoolMonitorPO> monitorDataList) {
        ThreadPoolOverviewVO overview = new ThreadPoolOverviewVO();

        if (monitorDataList.isEmpty()) {
            overview.setTotalExecutors(0L);
            overview.setTotalApps(0L);
            overview.setTotalActiveThreads(0);
            overview.setTotalRunningTasks(0);
            overview.setAvgMemoryUsage(0.0);
            overview.setDataPoints(0);
            return overview;
        }

        // 计算统计信息
        long totalExecutors = monitorDataList.stream()
                .map(ThreadPoolMonitorPO::getRegisterKey)
                .distinct()
                .count();

        long totalApps = monitorDataList.stream()
                .map(ThreadPoolMonitorPO::getAppName)
                .distinct()
                .count();

        int totalActiveThreads = monitorDataList.stream()
                .mapToInt(ThreadPoolMonitorPO::getActiveCount)
                .sum();

        int totalRunningTasks = monitorDataList.stream()
                .mapToInt(ThreadPoolMonitorPO::getRunningTaskCount)
                .sum();

        double avgMemoryUsage = monitorDataList.stream()
                .mapToDouble(data -> data.getMemoryUsagePercent().doubleValue())
                .average()
                .orElse(0.0);

        overview.setTotalExecutors(totalExecutors);
        overview.setTotalApps(totalApps);
        overview.setTotalActiveThreads(totalActiveThreads);
        overview.setTotalRunningTasks(totalRunningTasks);
        overview.setAvgMemoryUsage(avgMemoryUsage);
        overview.setDataPoints(monitorDataList.size());

        return overview;
    }

    /**
     * 计算环境监控概览数据
     */
    private EnvironmentOverviewVO calculateEnvironmentOverview(List<EnvironmentMonitorPO> envDataList) {
        EnvironmentOverviewVO overview = new EnvironmentOverviewVO();

        if (envDataList.isEmpty()) {
            overview.setTotalExecutors(0L);
            overview.setAvgCpuUsage(0.0);
            overview.setAvgMemoryUsage(0.0);
            overview.setAvgHeapMemoryUsage(0.0);
            return overview;
        }

        // 计算统计信息
        long totalExecutors = envDataList.stream()
                .map(EnvironmentMonitorPO::getRegisterKey)
                .distinct()
                .count();

        double avgCpuUsage = envDataList.stream()
                .mapToDouble(data -> data.getCpuUsagePercent().doubleValue())
                .average()
                .orElse(0.0);

        double avgMemoryUsage = envDataList.stream()
                .mapToDouble(data -> data.getSystemMemoryUsagePercent().doubleValue())
                .average()
                .orElse(0.0);

        double avgHeapMemoryUsage = envDataList.stream()
                .mapToDouble(data -> data.getHeapMemoryUsagePercent().doubleValue())
                .average()
                .orElse(0.0);

        overview.setTotalExecutors(totalExecutors);
        overview.setAvgCpuUsage(avgCpuUsage);
        overview.setAvgMemoryUsage(avgMemoryUsage);
        overview.setAvgHeapMemoryUsage(avgHeapMemoryUsage);

        return overview;
    }

    /**
     * 计算总体统计数据
     */
    private OverallStatisticsVO calculateOverallStatistics(
            ExecutorRuntimeOverviewVO runtimeOverview,
            ThreadPoolOverviewVO threadPoolOverview,
            EnvironmentOverviewVO environmentOverview) {
        
        OverallStatisticsVO overallStats = new OverallStatisticsVO();

        // 合并所有统计信息
        overallStats.setTotalExecutors(runtimeOverview.getTotalExecutors());
        overallStats.setOnlineExecutors(runtimeOverview.getOnlineExecutors());
        overallStats.setOfflineExecutors(runtimeOverview.getOfflineExecutors());
        overallStats.setHealthyExecutors(runtimeOverview.getHealthyExecutors());
        overallStats.setWarningExecutors(runtimeOverview.getWarningExecutors());
        overallStats.setErrorExecutors(runtimeOverview.getErrorExecutors());
        overallStats.setTotalActiveThreads(runtimeOverview.getTotalActiveThreads());
        overallStats.setTotalRunningTasks(runtimeOverview.getTotalRunningTasks());
        overallStats.setAverageMemoryUsage(runtimeOverview.getAverageMemoryUsage());

        // 计算健康率
        if (runtimeOverview.getTotalExecutors() > 0) {
            double healthRate = (double) runtimeOverview.getHealthyExecutors() / runtimeOverview.getTotalExecutors() * 100;
            overallStats.setHealthRate(Math.round(healthRate * 100.0) / 100.0);
        } else {
            overallStats.setHealthRate(0.0);
        }

        // 添加在线率
        if (runtimeOverview.getTotalExecutors() > 0) {
            double onlineRate = (double) runtimeOverview.getOnlineExecutors() / runtimeOverview.getTotalExecutors() * 100;
            overallStats.setOnlineRate(Math.round(onlineRate * 100.0) / 100.0);
        } else {
            overallStats.setOnlineRate(0.0);
        }

        return overallStats;
    }
}
